import React, { ChangeEvent, FC, useEffect, useRef, useState } from "react";
import {
  Button,
  Cascader,
  Checkbox,
  Col,
  Input,
  message,
  Row,
  Select,
  Table,
  Tabs,
} from "antd";
import { fetchRequest } from "@/utils/Request";
import { url } from "@/utils/url";
import "./index.css";
import { useRequest } from "@umijs/hooks";
import XLSX from "xlsx";
import exportExcel from "@/utils/exportExcel";
import { useHistory } from "react-router";

const { Option } = Select;
const { TabPane } = Tabs;

const AchievementTab: FC = () => {
  return (
    <>
      <Tabs className={"achievement-tab"}>
        <TabPane key={1} tab={"导出模板"}>
          <Achievement />
        </TabPane>
        <TabPane key={2} tab={"导入表格"}>
          <ImportTable />
        </TabPane>
      </Tabs>
    </>
  );
};

const Achievement: FC = () => {
  const [treeNode, setTreeNode] = useState<any>([]);
  const [subjectValue, setSubjectValue] = useState<any>([]);

  const [requestParamTree, setRequestParamTree] = useState<any>({
    level: 0,
    treeId: "0",
  });
  const [classValue, setClassValue] = useState([]);

  const { run: subRun, data: subData } = useRequest(
    (params) => fetchRequest(url.GET_SUBJECT_STUDENT, params),
    {
      manual: true,
      onSuccess: async (result, params) => {
        if (!result.success) {
          message.error(result.errorMsg);
          return;
        }
        console.log(result.data, subjectValue);
        /*拿到学生,以及生成的科目信息 生成excel*/

        const tempSub = {};
        subjectValue.map((item: any) => (tempSub[item.label] = ""));
        const resList = result.data.map((item: any) => {
          const tempItem = {};
          tempItem["学生学号"] = item.studentId;
          tempItem["学生名字"] = item.studentName;

          return {
            ...tempItem,
            ...tempSub,
          };
        });

        exportExcel(resList, "成绩模板.xlsx");
      },
    }
  );

  const { data } = useRequest(
    (params) =>
      fetchRequest(
        url.GET_SUBJECT,
        params ?? {
          deptId: "",
        }
      ),
    {
      onSuccess: async (result, params) => {
        if (!result.success) {
          message.error(result.errorMsg);
        }
      },
    }
  );

  //请求在校学生组织机构
  async function getSchoolOrganizationRequest(params: any) {
    try {
      const json = await fetchRequest(url.GET_SCHOOL_ORGANIZATION, params);
      if (json.success) {
        message.destroy();
        json.data.forEach((item: any) => {
          delete item.children;
        });
        setTreeNode(json.data);
      } else {
        message.destroy();
        message.error(json.errorMsg);
      }
    } catch (error: any) {
      message.destroy();
      message.error(error.message);
    }
  }

  const loadData = async (selectedOptions: any) => {
    const targetOption = selectedOptions[selectedOptions.length - 1];
    targetOption.loading = true;

    //组装参数
    const params: any = {
      level: 0,
      treeId: "0",
    };
    selectedOptions.forEach((item: any) => {
      params.treeId = item.treeId;
      params.level = selectedOptions.length;
    });
    // console.log(params)

    fetchRequest(url.GET_SCHOOL_ORGANIZATION, params)
      .then((json) => {
        if (json.success) {
          json.data.forEach((item: any) => {
            delete item.children;
          });
          targetOption.children = json.data;
          // console.log(targetOption)
        } else {
          message.error(json.errMsg);
        }
      })
      .catch((error) => {
        console.log(error);
      })
      .finally(() => {
        targetOption.loading = false;
        //主动刷新页面
        setTreeNode([...treeNode]);
      });
  };

  const onChangeClass = (value: any, selectedOptions: any) => {
    const select = value[value.length - 1];
    const flag = selectedOptions.find(
      (item: any) => item.value == select
    )?.isLeaf;

    if (selectedOptions.length === 0) {
      setClassValue([]);
      return;
    }

    if (flag) {
      setClassValue(() => value);
    } else {
      setClassValue([]);
    }
  };

  //点击导出按钮
  const onImport = async () => {
    if (!classValue[classValue.length - 1]) {
      message.error("请选择班级");
      return;
    }

    if (subjectValue.length <= 0) {
      message.error("请选择科目");
      return;
    }

    await subRun({ deptId: classValue[classValue.length - 1] });
  };

  const onChangeSubject = (value: any) => {
    setSubjectValue(value);
  };

  useEffect(() => {
    getSchoolOrganizationRequest(requestParamTree);
  }, [requestParamTree]);

  return (
    <>
      <div className={"achievement-wrapper"}>
        <div className={"search-wrapper"}>
          <div className={"title"}>班级选择:</div>
          <div>
            <Cascader
              placeholder="请选择班级"
              options={treeNode}
              loadData={loadData}
              value={classValue}
              changeOnSelect
              displayRender={(label) => label[label.length - 1]}
              onChange={onChangeClass}
              style={{ width: 300 }}
            />
          </div>
        </div>
        <div className={"search-wrapper subject"}>
          <div className={"title"}>科目选择:</div>
          <SubjectGroup
            onChangeSubject={onChangeSubject}
            subjectList={data?.data}
          />
        </div>
        <div className={"subject-btn"}>
          <Button type={"primary"} onClick={onImport}>
            导出模板到本地
          </Button>
        </div>
      </div>
    </>
  );
};

const SubjectGroup: FC<{
  onChangeSubject: (list: any) => void;
  subjectList: any;
}> = ({ onChangeSubject, subjectList }) => {
  const [indeterminate, setIndeterminate] = useState(false);
  const [checkAll, setCheckAll] = React.useState(false);

  const [checkedList, setCheckedList] = React.useState([]);

  const onCheckAllChange = (e: any) => {
    setCheckedList(
      e.target.checked ? subjectList.map((item: any) => item.value) : []
    );
    setIndeterminate(false);
    setCheckAll(e.target.checked);
  };

  const onChange = (list: any) => {
    setCheckedList(list);
    /*所选择科目item*/

    setIndeterminate(!!list.length && list.length < subjectList.length);
    setCheckAll(list.length === subjectList.length);
  };

  useEffect(() => {
    const subList = checkedList.map((item: number) =>
      subjectList.find((subItem: any) => subItem.value === item)
    );
    onChangeSubject(subList);
  }, [checkedList]);

  return (
    <>
      <div className={"subject-group"}>
        <Checkbox.Group onChange={onChange} value={checkedList}>
          <Row>
            {subjectList?.map((item: any) => (
              <Col span={4} key={item.value}>
                <Checkbox value={item.value}>{item.label}</Checkbox>
              </Col>
            ))}
          </Row>
        </Checkbox.Group>
        <Row>
          <Col offset={20}>
            <Checkbox
              indeterminate={indeterminate}
              onChange={onCheckAllChange}
              checked={checkAll}
            >
              <span style={{ color: "#1890ff" }}>全选/取消</span>
            </Checkbox>
          </Col>
        </Row>
      </div>
    </>
  );
};

const ImportTable: FC = () => {
  const input = useRef<HTMLInputElement>(null);
  const titleInput = useRef<any>(null);
  const [cols, setCols] = useState<any>([]);
  const [data, setData] = useState<any>([]);
  const [fileName, setFileName] = useState<any>("");
  const router = useHistory();
  const { run } = useRequest(
    (params) => fetchRequest(url.IMPORT_SCORE, params),
    {
      manual: true,
      onSuccess: async (result, params) => {
        if (!result.success) {
          const list = result?.data
            ? result?.data?.errorList?.map((item: any) =>
                message.error(item.errorTitle)
              )
            : message.error(result.errorMsg);

          return;
        }

        message.success(result.data);

        const id = setTimeout(() => {
          clearTimeout(id);
          router.go(0);
        }, 500);
      },
    }
  );

  const handleExcelFile = <T,>(file: File) => {
    let reader = new FileReader(); // 使用 FileReader 读取数据

    return new Promise<T>((resolve, reject) => {
      reader.onload = function (e) {
        // 数据读取完成后的回调函数
        try {
          let workbook = XLSX.read(e.target?.result, { type: "binary" });
          let firstSheetName = workbook.SheetNames[0]; // 获取第一个 sheet 的名字
          let worksheet = workbook.Sheets[firstSheetName]; // 获取第一个 sheet 的内容
          let res = XLSX.utils.sheet_to_json(worksheet) as unknown as T; // 使用 utils 里的方法转换内容为便于使用的数组
          resolve(res);
        } catch (e) {
          message.error("数据异常！");
          reject(e);
        }
      };
      reader.readAsBinaryString(file); // 读取数据
    });
  };

  const fileChange = async (e: ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      const list = await handleExcelFile<any[]>(file);
      console.log(list);

      setFileName(file.name);
      getCols(Object.keys(list[0]));
      getData(list);
    }
  };

  const getCols = (value: any) => {
    const list = value.map((item: any) => {
      return {
        title: item,
        dataIndex: item,
        key: item,
      };
    });

    setCols(list);
  };
  const getData = (value: any) => {
    setData(value.map((item: any) => item));
  };

  const onImport = async () => {
    const title = titleInput.current.input.value;
    if (!title) {
      message.error("请输入成绩标题");
      return;
    }

    if (!data.length) {
      message.error("请导入文件");
      return;
    }

    await run({
      title,
      list: data.map((item: any) => {
        const temp = { ...item };
        temp["学生名字"] = undefined;
        return temp;
      }),
      fileName,
    });
  };

  return (
    <>
      <div className={"achievement-wrapper"}>
        <div className={"search-wrapper"}>
          <div className={"title"}>成绩标题:</div>
          <div>
            <Input style={{ width: 400 }} ref={titleInput} />
          </div>
        </div>
        <div className={"title-hooks"}>
          <span>您填写的标题会以短信和微信的形式发送给家长，请勿随意填写!</span>
        </div>
        <div className={"search-wrapper subject"}>
          <div className={"title"}>上传文件:</div>
          <div>
            <input
              type="file"
              accept=".xlsx, .xls"
              onClick={(e: any) => (e.target.value = null)}
              onChange={(e) => fileChange(e)}
              ref={input}
            />
          </div>
        </div>

        <div className={"search-wrapper subject"}>
          <div className={"title"}>成绩预览:</div>
        </div>
        <div className={"subject-cs-table subject"}>
          <Table
            columns={cols}
            dataSource={data}
            rowKey={(item: any) => item["学生学号"]}
          />
        </div>
        <div className={"subject"}>
          <Button type={"primary"} onClick={onImport}>
            导入
          </Button>
        </div>
      </div>
    </>
  );
};

export default AchievementTab;
